home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLR / glrduckpond.c++ next >
C/C++ Source or Header  |  1996-11-11  |  10KB  |  425 lines

  1.  
  2. /* Copyright (c) Silicon Graphics, 1996. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. /* CC -o glrduckpond glrduckpond.c++ -lGLR -lglut -lInventor -lGL -lGLU -lXmu -lXext -lX11 -lm */
  9.  
  10. #include <stdio.h>
  11. #include <unistd.h>
  12.  
  13. #include <GL/gl.h>
  14. #include <GL/glu.h>
  15. #include <GL/glr.h>
  16. #include <GL/glut.h>
  17.  
  18. #include <Inventor/SoDB.h>
  19. #include <Inventor/SoInput.h>
  20. #include <Inventor/SbViewportRegion.h>
  21. #include <Inventor/nodes/SoSeparator.h>
  22. #include <Inventor/actions/SoGLRenderAction.h>
  23. #include <Inventor/nodes/SoCylinder.h>
  24. #include <Inventor/nodes/SoDirectionalLight.h>
  25. #include <Inventor/nodes/SoEventCallback.h>
  26. #include <Inventor/nodes/SoMaterial.h>
  27. #include <Inventor/nodes/SoPerspectiveCamera.h>
  28. #include <Inventor/nodes/SoRotationXYZ.h>
  29. #include <Inventor/nodes/SoTransform.h>
  30. #include <Inventor/nodes/SoTranslation.h>
  31. #include <Inventor/engines/SoElapsedTime.h>
  32. #include <Inventor/engines/SoGate.h>
  33. #include <Inventor/nodes/SoComplexity.h>
  34.  
  35. int first = 1;
  36. int quality = 1;
  37. int W = 300, H = 300;
  38. int timeout = 5000, waitTime = 250;
  39. int spinning = 0;
  40. int win;
  41. GLrSession session;
  42. GLrCanvasType canvasType;
  43. GLrCanvas canvas;
  44. GLubyte *image = NULL;
  45. int sceneChanged = 1;
  46. SoSeparator *localDuck, *remoteDuck, *root;
  47. SoRotationXYZ *duckRotXYZ, *localRot, *remoteRot;
  48. float angle = 0.0;
  49.  
  50. void
  51. reshape(int w, int h)
  52. {
  53.   float areaChange;
  54.  
  55.   areaChange = ((float) w*h)/((float) W*H) + 0.20; /* areaChange has 20% increase slop */
  56.   timeout = (int)((float) timeout * areaChange);
  57.   sceneChanged = 1;
  58.   glViewport(0, 0, w, h);
  59.   W = w;
  60.   H = h;
  61.   if (image)
  62.     free(image);
  63.   image = (GLubyte *) malloc(W * H * 3);
  64. }
  65.  
  66. void
  67. renderScene(void)
  68. {
  69.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  70.   SbViewportRegion myViewport(W, H);
  71.   SoGLRenderAction myRenderAction(myViewport);
  72.   myRenderAction.apply(root);
  73. }
  74.  
  75. void
  76. prepImageBlit(void)
  77. {
  78.   glMatrixMode(GL_PROJECTION);
  79.   glPushMatrix();
  80.   glLoadIdentity();
  81.   gluOrtho2D(0, W, 0, H);
  82.   glMatrixMode(GL_MODELVIEW);
  83.   glPushMatrix();
  84.   glLoadIdentity();
  85.   glDisable(GL_DEPTH_TEST);
  86. }
  87.  
  88. void
  89. postImageBlit(void)
  90. {
  91.   glMatrixMode(GL_PROJECTION);
  92.   glPopMatrix();
  93.   glMatrixMode(GL_MODELVIEW);
  94.   glPopMatrix();
  95.   glEnable(GL_DEPTH_TEST);
  96. }
  97.  
  98. void
  99. output(int x, int y, char *string)
  100. {
  101.   int len, i;
  102.  
  103.   glRasterPos2i(x, y);
  104.   len = (int) strlen(string);
  105.   for (i = 0; i < len; i++) {
  106.     glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
  107.   }
  108. }
  109.  
  110. void
  111. redraw(void)
  112. {
  113.   int status, attempt, expired;
  114.   char message[40];
  115.  
  116.   if(quality && !first) {
  117.     prepImageBlit();
  118.     if(sceneChanged) {
  119.       attempt = 0;
  120.       expired = 0;
  121.       glDrawBuffer(GL_FRONT);
  122.       glDisable(GL_LIGHTING);
  123.       do {
  124.         if(waitTime > 10) {
  125.       attempt++;
  126.       if(expired > 0) {
  127.             glColor3f(1.0, 0.0, 0.0);
  128.       } else {
  129.             glColor3f(1.0, 1.0, 1.0);
  130.       }
  131.       sprintf(message, "Interval: %-8d", timeout);
  132.           output(10, H - 10 - 10*attempt, message);
  133.       attempt++;
  134.     }
  135.  
  136.         status = glrBeginRenderInterval(canvas, W, H, timeout, waitTime);
  137.         if(status == 0) {
  138.       waitTime = 10;
  139.           glutSetWindow(win);
  140.           glDrawBuffer(GL_BACK);
  141.           postImageBlit();
  142.       goto localRender;
  143.         }
  144.     waitTime = 250;
  145.     root = remoteDuck;
  146.         renderScene();
  147.     glPixelStorei(GL_PACK_ALIGNMENT, 1);
  148.         glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
  149.         status = glrEndRenderInterval(canvas, &timeout);
  150.  
  151.         if(status == 0) {
  152.           glutSetWindow(win);
  153.       expired++;
  154.         }
  155.         timeout = (int)((float) timeout * 1.4);
  156.       } while(!status);
  157.       sceneChanged = 0;
  158.     }
  159.  
  160.     /* XXX Careful!  Versions of GLUT through 2.2.1 tried to cache the
  161.        current window/context binding to avoid unnecessary glXMakeCurrent
  162.        calls, but using GLR and GLUT together violates the assumption
  163.        that only GLUT called glXMakeCurrent. */
  164.     glutSetWindow(win);
  165.     glDrawBuffer(GL_BACK);
  166.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  167.     glRasterPos2i(0, 0);
  168.     glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
  169.     postImageBlit();
  170.     glFinish();
  171.     glutSwapBuffers();
  172.   } else {
  173.   localRender:
  174.     root = localDuck;
  175.     renderScene();
  176.     glFinish();
  177.     glutSwapBuffers();
  178.     if(first) {
  179.        first = 0;
  180.        glutPostRedisplay();
  181.     }
  182.   }
  183. }
  184.  
  185. int ms_attrs[] =
  186. {GLR_RGBA, GLR_RED_SIZE, 1, GLR_GREEN_SIZE, 1, GLR_BLUE_SIZE, 1, GLR_DEPTH_SIZE, 16, GLR_SAMPLES_SGIS, 4, 0};
  187. int attrs[] =
  188. {GLR_RGBA, GLR_RED_SIZE, 1, GLR_GREEN_SIZE, 1, GLR_BLUE_SIZE, 1, GLR_DEPTH_SIZE, 16, 0};
  189.  
  190. SoSeparator*
  191. duckScene(float complex)
  192. {
  193.    root = new SoSeparator;
  194.    root->ref();
  195.  
  196.    SoComplexity  *complexity     = new SoComplexity;
  197.    complexity->value = complex;
  198.    root->addChild(complexity);
  199.  
  200.    // Add a camera and light
  201.    SoPerspectiveCamera *myCamera = new SoPerspectiveCamera;
  202.    myCamera->position.setValue(0., -4., 8.0);
  203.    myCamera->heightAngle = M_PI/2.5; 
  204.    myCamera->nearDistance = 1.0;
  205.    myCamera->farDistance = 15.0;
  206.    root->addChild(myCamera);
  207.    root->addChild(new SoDirectionalLight);
  208.  
  209.    // Rotate scene slightly to get better view
  210.    SoRotationXYZ *globalRotXYZ = new SoRotationXYZ;
  211.    globalRotXYZ->axis = SoRotationXYZ::X;
  212.    globalRotXYZ->angle = M_PI/9;
  213.    root->addChild(globalRotXYZ);
  214.  
  215.    // Pond group
  216.    SoSeparator *pond = new SoSeparator; 
  217.    root->addChild(pond);
  218.    SoMaterial *cylMaterial = new SoMaterial;
  219.    cylMaterial->diffuseColor.setValue(0., 0.3, 0.8);
  220.    pond->addChild(cylMaterial);
  221.    SoTranslation *cylTranslation = new SoTranslation;
  222.    cylTranslation->translation.setValue(0., -6.725, 0.);
  223.    pond->addChild(cylTranslation);
  224.    SoCylinder *myCylinder = new SoCylinder;
  225.    myCylinder->radius.setValue(4.0);
  226.    myCylinder->height.setValue(0.5);
  227.    pond->addChild(myCylinder);
  228.  
  229.    // Duck group
  230.    SoSeparator *duck = new SoSeparator;
  231.    root->addChild(duck);
  232.  
  233.    // Read the duck object from a file and add to the group
  234.    SoInput myInput;
  235.    if (!myInput.openFile("duck.iv")) {
  236.      if (!myInput.openFile("/usr/share/src/Inventor/examples/data/duck.iv")) {
  237.        return NULL;
  238.      }
  239.    }
  240.    SoSeparator *duckObject = SoDB::readAll(&myInput);
  241.    if (duckObject == NULL) return NULL;
  242.  
  243.    // Set up the duck transformations
  244.    duckRotXYZ = new SoRotationXYZ;
  245.    duck->addChild(duckRotXYZ);
  246.    duckRotXYZ->angle = angle;
  247.    duckRotXYZ->axis = SoRotationXYZ::Y;  // rotate about Y axis
  248.    SoTransform *initialTransform = new SoTransform;
  249.    initialTransform->translation.setValue(0., 0., 3.);
  250.    initialTransform->scaleFactor.setValue(6., 6., 6.);
  251.    duck->addChild(initialTransform);
  252.  
  253.    duck->addChild(duckObject);
  254.  
  255.    return root;
  256. }
  257.  
  258. void
  259. updateModels(void)
  260. {
  261.   sceneChanged = 1;
  262.   localRot->angle = angle;
  263.   remoteRot->angle = angle;
  264.   glutPostRedisplay();
  265. }
  266.  
  267. void
  268. animate(void)
  269. {
  270.   angle += 0.1;
  271.   updateModels();
  272. }
  273.  
  274. void
  275. setAnimation(int enable)
  276. {
  277.         if(enable) {
  278.             quality = 0;
  279.             spinning = 1;
  280.             glutIdleFunc(animate);
  281.        } else {
  282.             sceneChanged = 1;
  283.             quality = 1;
  284.             spinning = 0;
  285.             glutIdleFunc(NULL);
  286.             sceneChanged = 1;
  287.             glutPostRedisplay();
  288.        }
  289. }
  290.  
  291. /* ARGSUSED */
  292. void
  293. keyboard(unsigned char ch, int x, int y)
  294. {
  295.   if(ch == ' ') {
  296.     setAnimation(0);
  297.     animate();
  298.   }
  299. }
  300.  
  301. void
  302. menuSelect(int item)
  303. {
  304.    switch(item) {
  305.    case 1:
  306.      animate();
  307.      break;
  308.    case 2:
  309.       if(!spinning) {
  310.             setAnimation(1);
  311.        } else {
  312.             setAnimation(0);
  313.        }
  314.       break;
  315.    }
  316. }
  317.  
  318. void
  319. vis(int visible)
  320. {
  321.   if (visible == GLUT_VISIBLE) {
  322.     if (spinning)
  323.       glutIdleFunc(animate);
  324.   } else {
  325.     if (spinning)
  326.       glutIdleFunc(NULL);
  327.   }
  328. }
  329.  
  330. void
  331. gfxinit(void)
  332. {
  333.   glEnable(GL_DEPTH_TEST);
  334.   glClearColor(0.132, 0.542, 0.132, 1.0);
  335. }
  336.  
  337. int moving  = 0;
  338. int begin;
  339.  
  340. /* ARGSUSED */
  341. void
  342. mouse(int button, int state, int x, int y)
  343. {
  344.   if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  345.     setAnimation(0);
  346.     moving = 1;
  347.     begin = x;
  348.     quality = 0;
  349.   }
  350.   if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
  351.     moving = 0;
  352.     quality = 1;
  353.     sceneChanged = 1;
  354.     glutPostRedisplay();
  355.   }
  356. }
  357.  
  358. /* ARGSUSED */
  359. void
  360. motion(int x, int y)
  361. {
  362.   if (moving) {
  363.     angle = angle + .01 * (x - begin);
  364.     begin = x;
  365.     updateModels();
  366.   }
  367. }
  368.  
  369. void
  370. main(int argc, char **argv)
  371. {
  372.   glutInit(&argc, argv);
  373.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  374.  
  375.   SoDB::init();
  376.  
  377.   localDuck = duckScene(0.4);
  378.   if(localDuck == NULL) {
  379.     fprintf(stderr, "couldn't read IV file\n");
  380.     exit(1);
  381.   }
  382.   localRot = duckRotXYZ;
  383.  
  384.   remoteDuck = duckScene(0.9);
  385.   if(remoteDuck == NULL) {
  386.     fprintf(stderr, "couldn't read IV file\n");
  387.     exit(1);
  388.   }
  389.   remoteRot = duckRotXYZ;
  390.  
  391.   session = glrOpenSession(NULL);
  392.   if (session == NULL) {
  393.     fprintf(stderr, "couldn't get GLR session\n");
  394.     exit(1);
  395.   }
  396.   canvasType = glrGetCanvasType(session, ms_attrs);
  397.   if (canvasType == NULL) {
  398.     canvasType = glrGetCanvasType(session, attrs);
  399.     if (canvasType == NULL) {
  400.       fprintf(stderr, "couldn't get usable canvas type\n");
  401.       exit(1);
  402.     }
  403.   }
  404.   canvas = glrCreateCanvas(canvasType, NULL);
  405.  
  406.   glrEstablishRenderState(canvas);
  407.   gfxinit();
  408.  
  409.   glutInitWindowSize(W, H);
  410.   win = glutCreateWindow("GLUT Inventor Multisampling");
  411.   glutDisplayFunc(redraw);
  412.   glutReshapeFunc(reshape);
  413.   glutCreateMenu(menuSelect);
  414.   glutAddMenuEntry("Step", 1);
  415.   glutAddMenuEntry("Toggle animation", 2);
  416.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  417.   glutKeyboardFunc(keyboard);
  418.   glutMouseFunc(mouse);
  419.   glutMotionFunc(motion);
  420.   glutVisibilityFunc(vis);
  421.   gfxinit();
  422.  
  423.   glutMainLoop();
  424. }
  425.